<?php
/**
 * tinymvc超轻量级PHP开发框架
 *
 * @author    Lansn
 * @copyright Copyright (c) 2024-2025
 * @license   tinymvc 遵循Apache2开源协议发布，需保留开发者信息。
 * @link      http://173654757.xyz
 */

namespace system\core;

use Flight;
use think\facade\Db as ThinkDb;

class Application
{
    protected array  $appConfig;

    public function __construct()
    {
        $this->init();
    }

    protected function init(): void
    {
        $this->appConfig = config('app');

        // 设置应用时区
        $timezone = $this->appConfig['timezone'];
        date_default_timezone_set($timezone);

        // 根据debug配置决定是否启用错误处理  
        if ($this->appConfig['debug']) {
            // 开发环境：启用Flight的错误捕获  
            Flight::set('flight.handle_errors', true); 

            error_reporting(E_ALL);
            ini_set('display_errors', '1');
            
        } else {  
            // 生产环境：禁用Flight的错误捕获  
            Flight::set('flight.handle_errors', false);  

            error_reporting(E_ALL);
            ini_set('display_errors', '0');      // 不显示错误给用户看
            ini_set('log_errors', '1');          // 开启日志记录
            ini_set('error_log', ROOT_PATH . 'runtime/logs/error/php_error.log'); // 可选日志路径
        }

         // 加载应用内置函数
        if (file_exists(APP_PATH.'functions.php')) {
            require_once APP_PATH.'functions.php';
        }

        // 初始化数据库连接配置（仅一次）
        static $dbInit = false;
        if (!$dbInit && ($this->appConfig['database'] ?? false)) {
            ThinkDb::setConfig(config('database'));
            $dbInit = true;
        }
    }

    protected function register(): void
    {
        // 注册扩展类
        Flight::register('session',  \flight\Session::class, [[
            'save_path'   => ROOT_PATH . 'runtime/sessions', // Custom directory for storing session files
            'auto_commit' => true, // Automatically commit session changes on shutdown
            'start_session' => true, 
        ]]);
        Flight::register('request',  \system\core\Request::class);
        Flight::register('response', \system\core\Response::class);
        // 注册定义类
        require_once ROOT_PATH . 'config/register.php';
    }

    protected function events(): void
    {
        // 注册事件监听器
        require_once ROOT_PATH . 'config/events.php';
    }

    protected function security(): void
    {
        // 安全性设置
        require_once ROOT_PATH . 'config/security.php';
    }

    protected function router(): void
    {
        $defaultModule     = $this->appConfig['default_module'] ?? 'home';
        $defaultController = $this->appConfig['default_controller'] ?? 'Index';
        $defaultAction     = $this->appConfig['default_action'] ?? 'index';

        // 加载自定义路由
        $routerFile = ROOT_PATH . 'config/router.php';
        if (file_exists($routerFile)) {
            $routes = include $routerFile;
            foreach ($routes as $route) {
                [$method, $path, $handler] = $route;
                Flight::route(strtoupper($method) . ' ' . $path, $handler);
            }
        }

        // 默认路由，支持伪静态后缀
        Flight::route('*', function () use ($defaultModule, $defaultController, $defaultAction)
        {
            $uri = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');

            $urlSuffix = config('app.url_suffix') ?? '';
            // 去除伪静态后缀（如 .html）
            if (!empty($urlSuffix) && str_ends_with($uri, $urlSuffix)) {
                $uri = substr($uri, 0, -strlen($urlSuffix));
            }

            $segments = array_filter(explode('/', $uri));

            // 去除 index.php
            if (!empty($segments) && $segments[0] === 'index.php') {
                array_shift($segments);
            }

            $segments = array_values($segments);
            $module = $defaultModule;
            $controller = $defaultController;
            $action = $defaultAction;
            $params = [];

            // 判断第一个 segment 是否为有效模块目录
            $possibleModule = $segments[0] ?? '';
            $isModule = is_dir(APP_PATH . '/' . $possibleModule);

            if ($isModule) {
                $module     = array_shift($segments) ?? $defaultModule;
                $controller = ucfirst(array_shift($segments) ?? $defaultController);
                $action     = array_shift($segments) ?? $defaultAction;
            } else {
                $controller = ucfirst(array_shift($segments) ?? $defaultController);
                $action     = array_shift($segments) ?? $defaultAction;
            }

            $params = $segments;

            $controllerClass = "\\app\\{$module}\\controller\\{$controller}Controller";
            $actionMethod    = $action . 'Action';

            // 自动加载模块函数文件
            if (file_exists(APP_PATH . $module . '/functions.php')) {
                require_once(APP_PATH . $module . '/functions.php');
            }

            $instance = new $controllerClass($module, $controller, $action);

            // 可选参数数量判断
            $reflection = new \ReflectionMethod($controllerClass, $actionMethod);
            $requiredParams = $reflection->getNumberOfRequiredParameters();

            // 参数长度不足时自动填空 或 抛异常
            if (count($params) < $requiredParams) {
                // $params = array_pad($params, $requiredParams, null);
                throw new \Exception("Missing required parameters for $controllerClass::$actionMethod");
            }

            call_user_func_array([$instance, $actionMethod], $params);
        });
    }

    public function run(): void
    {
        // 设置路由规则
        $this->router();

        // 注册类
        $this->register();

        // 注册事件监听器
        $this->events();

        // 安全性设置
        $this->security();

        // 启动应用
        Flight::start();

    }
}
